//
// Created by huayang on 9/20/19.
//

#ifndef RPCLOG_RLOG_IMPL_H
#define RPCLOG_RLOG_IMPL_H

#include "thread.h"
#include <cassert>

typedef std::function<void(int, const std::string&, const std::string)> LogTaskCallback;

class RLogImpl {
public:

    static RLogImpl* Self() {
        static RLogImpl self;
        return &self;
    }

    void AttachLoggingThread(sptr<common::Thread> thread)
    {
        assert(thread != nullptr);
        t_ = thread;
    }

    void Info(const string& tag, const string& msg);
    void Debug(const string& tag, const string& msg);
    void Warn(const string& tag, const string& msg);
    void Error(const string& tag, const string& msg);

    LogTaskCallback GetTaskCallback()
    {
        return log_callback_;
    }

    void RegisterTaskCallback(LogTaskCallback cb)
    {
        log_callback_ = std::move(cb);
    }

private:

    sptr<common::Thread> t_{nullptr};

    LogTaskCallback       log_callback_;
};

class LogTask : public common::ThreadTask {
public:
    LogTask(RLogImpl* impl, int level, std::string tag, std::string msg)
            :impl_(impl), level_(level), tag_(std::move(tag)), msg_(std::move(msg))
    {}

    void Run() override
    {
        assert(impl_ != nullptr);
        assert(impl_->GetTaskCallback() != nullptr);
        impl_->GetTaskCallback()(level_, tag_, msg_);
    }

private:
    int             level_ = 0;
    std::string     tag_;
    std::string     msg_;
    RLogImpl*       impl_{nullptr};
};

#endif //RPCLOG_RLOG_IMPL_H
